package brain.mapa;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Mapa
 * @author Jorge Lainfiesta 11142
 * @since Aug 31, 2012
 * @version 1
 */
public class Mapa {

    private ArrayList<Coordenada> galletas;
    private ArrayList<Coordenada> obstaculos;
    private Coordenada inicio;
    private int ancho;
    private int alto;
    private Element docRoot;
    
    /**
     * Constructor
     * @param file
     * @throws Exception si fallta algo con el mapa que se intenta cargar
     */
    public Mapa(InputStream file) throws Exception{
        galletas = new ArrayList<Coordenada>();
        obstaculos = new ArrayList<Coordenada>();
        //Parseamos documento
        Document doc;
        try{
            doc = parseXML(file);
        }catch(Exception e){
            throw e;
        }
        docRoot = doc.getDocumentElement();        //Obtenemos raiz del doc
        //Obtenemos datos de la raiz
        ancho = Integer.parseInt(docRoot.getAttribute("ancho"));
        alto  = Integer.parseInt(docRoot.getAttribute("alto"));
        int start_x = Integer.parseInt(docRoot.getAttribute("inicio_x"));
        int start_y = Integer.parseInt(docRoot.getAttribute("inicio_y"));
        //Fijamos posicion inicial y rangos
        inicio = new Coordenada(start_x,start_y);
        inicio.setRange(ancho, alto);
        //Obtenemos listas de coordenadas
        galletas = getCoordList("galleta");
        obstaculos = getCoordList("obstaculo");
    }
    /**
     * Parsea un archivo XML a Document Object Model
     * @param file
     * @return Documento de XML parseado
     * @throws IOException 
     */
    private Document parseXML(InputStream file) throws IOException{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();  //Obtenemos instancia
            Document dom = db.parse(file);       //Parseamos documento
            return dom;
        }
        //Reportamos excepciones
        catch(ParserConfigurationException pce) {
            pce.printStackTrace();
        }catch(SAXException se) {
            se.printStackTrace();
        }catch(IOException ioe) {
            ioe.printStackTrace();
        }
        return null;
    }
    
    /**
     * Retorna una lista de coordenadas de la tag pasada
     * @param tagname Puede ser "galleta" o "obstaculo"
     * @return Lista de coordenadas de la tag
     */
    private ArrayList<Coordenada> getCoordList(String tagname){
        ArrayList<Coordenada> result = new ArrayList<Coordenada>();
        NodeList galletasEls = docRoot.getElementsByTagName(tagname);
        for(int i = 0; i < galletasEls.getLength(); i++){
            Element galleta = (Element) galletasEls.item(i);
            //Obtenemos posiciones de la galleta
            int x_pos = Integer.parseInt(galleta.getAttribute("x"));
            int y_pos = Integer.parseInt(galleta.getAttribute("y"));
            //Creamos coordenada y la agregamos a la lista
            Coordenada coord = new Coordenada(x_pos, y_pos);
            result.add(coord);
        }
        
        return result;
    }

    /**
     * @return the galletas
     */
    public ArrayList<Coordenada> getGalletas() {
        return galletas;
    }

    /**
     * @return the obstaculos
     */
    public ArrayList<Coordenada> getObstaculos() {
        return obstaculos;
    }

    /**
     * @return the inicio
     */
    public Coordenada getInicio() {
        return inicio;
    }

    /**
     * @return the ancho
     */
    public int getAncho() {
        return ancho;
    }

    /**
     * @return the alto
     */
    public int getAlto() {
        return alto;
    }
}
